// 11.1 使用关联容器
/**
 * map类型通常被称为关联数组（associative array）。
 * 关联数组与“正常”数组类似，不同之处在于其下标不必是整数。我们通过一个关键字而不是位置来查找值。
 * 与之相对，set就是关键字的简单集合。
 * 当只是想知道一个值是否存在时，set是最有用的。例如，一个企业可以定义一个名为bad_checks的set来保存那些曾经开过空头支票的人的名字。
 */

#include <iterator>
#include <vector>
#include <list>
#include <deque>
#include <forward_list>
#include <string>
#include <array>
#include <stack>
#include <queue>
#include <algorithm>
#include <numeric>
using std::swap;
using std::vector, std::list, std::deque, std::forward_list, std::string, std::array, std::stack, std::queue;
#include "../Chapter07/Sales_data.h"
#include <iostream>
using std::begin, std::cbegin, std::end, std::cend, std::find, std::accumulate, std::equal, std::fill, std::fill_n, std::back_inserter;
using std::cin, std::cout, std::endl;
using std::copy, std::replace, std::replace_copy;
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
using namespace std;

int main()
{
    // 使用map
    // 一个经典的使用关联数组的例子是单词计数程序
    map<string, size_t> word_count; // string到size_t的空map
    string word;
    while (cin >> word)
    {
        ++word_count[word]; // 提取word的计数器并将其加1
    }
    for (const auto &w : word_count) // 对map中的每个元素
    {
        cout << w.first << " occurs " << w.second << (w.second > 1 ? "times" : "time") << endl; // 打印结果
    }
    // 类似顺序容器，关联容器也是模板（参见3.3节，第86页）。为了定义一个map，我们必须指定关键字和值的类型。

    // 使用set
    // 使用set保存想要忽略的单词
    set<string> exclude = {"The", "But", "And", "Or", "An", "A", "the", "but", "and", "or", "an", "a"};
    while (cin >> word)
    {
        if (exclude.find(word) == exclude.end()) // 只统计不在exclude中的单词
        {
            ++word_count[word]; // 提取word的计数器并将其加1
        }
    }

    return 0;
}